package com.flying.invest.invest.service;

import java.util.Date;
import java.util.List;

import com.flying.common.annotation.DaoCreate;
import com.flying.common.annotation.DaoQuery;
import com.flying.common.annotation.DaoRemove;
import com.flying.common.annotation.DaoUpdate;
import com.flying.common.annotation.Transaction;
import com.flying.common.util.Codes;
import com.flying.framework.annotation.MethodInfo;
import com.flying.framework.annotation.Param;
import com.flying.framework.annotation.Service;
import com.flying.framework.context.ServiceContext;
import com.flying.framework.exception.AppException;
import com.flying.framework.model.ActionResult;
import com.flying.framework.model.ModelFactory;
import com.flying.framework.model.QueryResult;
import com.flying.framework.security.Principal;
import com.flying.framework.service.AbstractService;
import com.flying.invest.invest.TransactionType;
import com.flying.invest.invest.model.Investment;
import com.flying.invest.invest.model.InvestmentSuggestion;
import com.flying.invest.invest.model.InvestmentSuggestion.Status;
import com.flying.invest.invest.model.InvestmentTransaction;
import com.flying.invest.invest.model.InvestmentTransaction.Method;
import com.flying.invest.invest.model.InvestmentTransaction.Objective;
import com.flying.invest.strategy.model.Strategy;

@Service(value="InvestmentSuggestionService", desc="策略建议")
public class InvestmentSuggestionService extends AbstractService{
    private InvestmentTransactionService ts;
	private InvestmentService vs;
    public void setInvestmentTransactionService(InvestmentTransactionService s) {
    	this.ts = s;
    }
	public void setInvestmentService(InvestmentService s) {
		this.vs = s;
	}
    
	@MethodInfo("新增")
	@DaoCreate(entity=InvestmentSuggestion.ENTITY_NAME)
	public InvestmentSuggestion create(
			@Param(value=InvestmentSuggestion.USER_ID, required=true,	desc="所属用户") Long user_id,
			@Param(value=InvestmentSuggestion.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=InvestmentSuggestion.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id,
			@Param(value=InvestmentSuggestion.BATCH_NUM, required=true,	desc="批号") Integer batch_num,
			@Param(value=InvestmentSuggestion.NAME, required=false,	desc="名称") String name,
			@Param(value=InvestmentSuggestion.REMARKS, required=false,	desc="说明") String remarks,
			@Param(value=InvestmentSuggestion.EXTRA, required=false,	desc="附加信息") String extra,
			@Param(value=InvestmentSuggestion.TRANSACTION_TYPE, required=true,	desc="交易类型", enumClass=TransactionType.class) Integer transaction_type,
			
			@Param(value=InvestmentSuggestion.AMOUNT, required=true,	desc="金额") Double amount,
			@Param(value=InvestmentSuggestion.QUANTITY, required=false,	desc="交易数量") Double quantity,
			@Param(value=InvestmentSuggestion.FROM_DATE, required=false,	desc="开始日期") Date from_date,
			@Param(value=InvestmentSuggestion.TO_DATE, required=false,	desc="截至日期") Date to_date,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class) Integer status,
			@Param(value=InvestmentSuggestion.CREATOR, required=false,	desc="创建人") String creator,
			@Param(value=InvestmentSuggestion.CREATE_TIME, required=false,	desc="创建时间") Date create_time
		) {
		Principal p = ServiceContext.getContext().getPrincipal();
		return ModelFactory.create(InvestmentSuggestion.class, 
				InvestmentSuggestion.STATUS, Status.PREPARING.value,
				InvestmentSuggestion.CREATOR, creator == null?(p == null?null: p.getName()): creator,
				InvestmentSuggestion.CREATE_TIME, create_time == null?new Date(): create_time);
	}

	@Transaction
	public ActionResult createTransaction(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id) throws Exception {
		InvestmentSuggestion g = this.findById(suggestion_id);
		if(g.getStatus() != Status.PREPARING.value()) {
			throw new AppException("0101","建议["+g.getName()+"]状态不是待执行，不能创建交易！");
		}
		if(g.getTransactionId() != null) {
			throw new AppException("0101","建议["+g.getName()+"]已经创建交易！");
		}
		Investment v = this.vs.findById(g.getInvestId());
		InvestmentTransaction t = this.ts.create(v.getInvestId(), v.getAssetsId(), v.getUserId(), suggestion_id, g.getStrategyId(), g.getTransactionType(), Method.STRATEGIED.value(), Objective.TRANS.value(), 
				g.getAmount(), g.getQuantity(), null, v.getPrice(), v.getCurrency(), null, g.getBatchNum(), null, g.getRemarks(), null, null, null);
		return this.updateTransactionStatus(suggestion_id, Status.ORDERED.value(), t.getTransactionId(), null, null, null);
	}
	
	@MethodInfo("修改")
	@DaoUpdate(entity=InvestmentSuggestion.ENTITY_NAME)
	public ActionResult update(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id,
			@Param(value=InvestmentSuggestion.BATCH_NUM, required=true,	desc="批号") Integer batch_num,
			@Param(value=InvestmentSuggestion.NAME, required=false,	desc="名称") String name,
			@Param(value=InvestmentSuggestion.REMARKS, required=false,	desc="说明") String remarks,
			@Param(value=InvestmentSuggestion.TRANSACTION_TYPE, required=true,	desc="交易类型", enumClass=TransactionType.class) Integer transaction_type,
			
			@Param(value=InvestmentSuggestion.AMOUNT, required=true,	desc="金额") Double amount,
			@Param(value=InvestmentSuggestion.QUANTITY, required=false,	desc="交易数量") Double quantity,
			@Param(value=InvestmentSuggestion.FROM_DATE, required=false,	desc="开始日期") Date from_date,
			@Param(value=InvestmentSuggestion.TO_DATE, required=false,	desc="截至日期") Date to_date,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class) Integer status,
			@Param(value=InvestmentSuggestion.TRANSACTION_DATE, required=false,	desc="交易日期") Date transaction_date,
			@Param(value=InvestmentSuggestion.TRANSACTION_ID, required=false,	desc="交易ID") Long transaction_id,
			
			@Param(value=InvestmentSuggestion.UPDATOR, required=false,	desc="修改人") String updator,
			@Param(value=InvestmentSuggestion.UPDATE_TIME, required=false,	desc="修改时间") Date update_time
		) throws Exception {
		Principal p = ServiceContext.getContext().getPrincipal();
		return ModelFactory.create(ActionResult.class, 
				InvestmentSuggestion.UPDATOR, (p == null?null: p.getName()),
				InvestmentSuggestion.UPDATE_TIME, new Date());
	}
	
	@MethodInfo("修改")
	@DaoUpdate(entity=InvestmentSuggestion.ENTITY_NAME, expectedEffectRows=1)
	protected ActionResult updateTransactionStatus(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class) Integer status,
			@Param(value=InvestmentSuggestion.TRANSACTION_ID, required=false,	desc="交易ID") Long transaction_id,
			@Param(value=InvestmentSuggestion.TRANSACTION_DATE, required=false,	desc="交易日期") Date transaction_date,
			@Param(value=InvestmentSuggestion.UPDATOR, required=false,	desc="修改人") String updator,
			@Param(value=InvestmentSuggestion.UPDATE_TIME, required=false,	desc="修改时间") Date update_time) {
		Principal p = ServiceContext.getContext().getPrincipal();
		return ModelFactory.create(ActionResult.class, 
				InvestmentSuggestion.UPDATOR, (p == null?null: p.getName()),
				InvestmentSuggestion.UPDATE_TIME, new Date());
	}

	@MethodInfo("修改")
	@DaoUpdate(entity=InvestmentSuggestion.ENTITY_NAME)
	public ActionResult cancel(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id,
			@Param(value=InvestmentSuggestion.CANCEL_TYPE,   required=true,   desc="取消类型" ) Integer cancelType,
			@Param(value=InvestmentSuggestion.CANCEL_MSG,   required=false,   maxlength=4000,	desc="取消说明" ) String cancelMsg,
			@Param(value=InvestmentSuggestion.CANCEL_DATE,   required=false,  desc="取消时间" ) Date cancelDate,
			@Param(value=InvestmentSuggestion.UPDATOR, required=false,	desc="修改人") String updator,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class) Integer status
		) {
		InvestmentSuggestion g = this.findById(suggestion_id);
		if(g.getStatus() != Status.PREPARING.value()) {
			throw new AppException("0101","建议["+g.getName()+"]状态不是待执行，不能取消！");
		}
		Principal p = ServiceContext.getContext().getPrincipal();
		return ModelFactory.create(ActionResult.class, 
				InvestmentSuggestion.STATUS, Status.CANCELED.value,
				InvestmentSuggestion.UPDATOR, (p == null?null: p.getName()),
				InvestmentSuggestion.CANCEL_DATE, new Date());
	}

	@Transaction
	public ActionResult closeAllActivesByInvestId(
			@Param(value=Strategy.INVEST_ID, required=true,	desc="投资项目") Long invest_id,
			@Param(value=Strategy.UPDATOR, required=false,	desc="修改人") String updator,
			@Param(value=Strategy.UPDATE_TIME, required=false,	desc="修改时间") Date update_time) {
		List<InvestmentSuggestion> list = this.findAll(null, invest_id, null, 
				new Integer[] {Status.PREPARING.value}, 0, 10000).getRows();
		list.stream().forEach(x -> {
			this.cancel(x.getSuggestionId(), -1, "Closed for investment!", new Date(), updator, Status.CANCELED.value);
		});
		return ModelFactory.create(ActionResult.class, Codes.CODE, Codes.SUCCESS);
	}

	@MethodInfo("删除")
	@DaoRemove(entity=InvestmentSuggestion.ENTITY_NAME)
	public ActionResult remove(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id
		) throws Exception {
		return null;
	}

	@SuppressWarnings("unchecked")
	@MethodInfo("搜索")
	@DaoQuery(entity=InvestmentSuggestion.ENTITY_NAME, pageable=true, modelClass=InvestmentSuggestion.class, osql="order by create_time desc")
	public QueryResult<InvestmentSuggestion> findAll(
			@Param(value=InvestmentSuggestion.USER_ID, required=false,	desc="所属用户") Long user_id,
			@Param(value=InvestmentSuggestion.INVEST_ID, required=false,	desc="投资ID") Long invest_id,
			@Param(value=InvestmentSuggestion.STRATEGY_ID, required=false,	desc="策略ID") Long strategy_id,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class, tag="IN") Integer[] status,
			@Param(value=Codes.PAGE_NUM, 	required=false, desc="分页页号，默认0") int page,
			@Param(value=Codes.PAGE_SIZE, 	required=false, desc="分页大小，默认10") int rows) {
		Principal p = ServiceContext.getContext().getPrincipal();
		if(user_id == null && p != null) {
			user_id = Long.parseLong(p.getId());
		}
		return ModelFactory.create(QueryResult.class, InvestmentSuggestion.USER_ID, user_id);
	}

	@MethodInfo("搜索")
	@DaoQuery(entity=InvestmentSuggestion.ENTITY_NAME, pageable=true, modelClass=InvestmentSuggestion.class, 
		osql="order by create_time desc")
	public QueryResult<InvestmentSuggestion> findByStrategyId(
			@Param(value=InvestmentSuggestion.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class, tag="IN") Integer[] status) {
		return null;
	}

	@MethodInfo("搜索")
	@DaoQuery(entity=InvestmentSuggestion.ENTITY_NAME, pageable=true, modelClass=InvestmentSuggestion.class, 
		qsql="select * from v_investment_suggestion_strategy t", 
		csql="select count(0) as c from v_investment_suggestion_strategy t",
		osql="order by create_time desc")
	public QueryResult<InvestmentSuggestion> findByStrategyTypeIdAndInvestId(
			@Param(value=Strategy.TYPE_ID, required=true,	desc="策略类型ID") Long type_id,
			@Param(value=InvestmentSuggestion.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=InvestmentSuggestion.STATUS, required=false,	desc="状态", enumClass=Status.class, tag="IN") Integer[] status) {
		return null;
	}

	@MethodInfo("查询")
	@DaoQuery(entity=InvestmentSuggestion.ENTITY_NAME, single=true, throwsNotFoundException=true )
	public InvestmentSuggestion findById(
			@Param(value=InvestmentSuggestion.SUGGESTION_ID, required=true,	desc="建议ID") Long suggestion_id
		) {
		return null;
	}

}